home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / PASCAL / 0189.ZIP / FILER.PAS < prev    next >
Pascal/Delphi Source File  |  1986-02-09  |  37KB  |  1,082 lines

  1. (***************************************************************)
  2. (*                                                             *)
  3. (*        FILER A LA PASCAL DATA BASE SOURCE CODE FILE         *)
  4. (*                                                             *)
  5. (*        (C) 1985 by  John M. Harlan                          *)
  6. (*                     24000 Telegraph                         *)
  7. (*                     Southfield, MI. 48034                   *)
  8. (*                                                             *)
  9. (*     The FILER GROUP of programs is released on a "FREE      *)
  10. (*     SOFTWARE" basis.  The recipient is free to examine      *)
  11. (*     and use the software with the understanding that if     *)
  12. (*     the FILER GROUP of programs prove to be of use and      *)
  13. (*     value,  a contribution to the author is encouraged.     *)
  14. (*                                                             *)
  15. (*     While reasonable effort has been made to ensure the     *)
  16. (*     reliability of the FILER GROUP of programs, no war-     *)
  17. (*     ranty is given. The recipient uses the programs at      *)
  18. (*     his own risk  and in no event shall the author be       *)
  19. (*     liable for damages arising from their use.              *)
  20. (*                                                             *)
  21. (*                                                             *)
  22. (***************************************************************)
  23.  
  24.  
  25. { Formatted 2/7/86 by Doug Stevens using Pformat and the Turbo
  26.   editors global search/replace. Original version was 100%
  27.   upper case and very hard to read. }
  28.  
  29. program filer;
  30. {$C-}                       { make ctrl c and ctrl s inoperative }
  31. {  A DATA BASE PROGRAM WRITTEN IN TURBO PASCAL FOR PC-DOS COMPUTERS  }
  32. {  FILER.PAS VERSION 2.0 }
  33. {  INCLUDE FILES : FILER1.PAS, FILER2.PAS, FILER3.PAS, FILER4.PAS }
  34. {  JUNE 28, 1985  }
  35.  
  36. label              FLIERSTART;
  37.  
  38. type
  39.   Range          = array[1..256] of char;
  40.   String60       = string[60];
  41.   NameStr        = string[12];
  42.  
  43. const
  44.   hilight          : string[3]  = ' ';
  45.   lowlight         : string[3]  = '';
  46.  
  47. var
  48.   filerecchgd      : boolean;
  49.   condition        : boolean;
  50.   changedate       : boolean;
  51.   abortchar        : boolean;
  52.   recaddedtofile   : boolean;
  53.   fileexists       : boolean;
  54.  
  55.   ch,ch1,option    : char;
  56.   searchtype       : char;
  57.  
  58.   filename       : string[6];
  59.   filedate,
  60.   currdate       : string[8];
  61.   sourcename     : string[14];
  62.   ans            : String60;
  63.   target         : String60;
  64.   lasttarget     : String60;
  65.   message        : String60;
  66.  
  67.   w,x,z, code, count, value, len,
  68.   maxnbrrec, nbrrecused, rcdlen,
  69.   blockingfactor, fieldperrecord,
  70.   datarecord, diskrecord, precbyte,
  71.   diskrecnowinmem, nbrdiskrecused,
  72.   lastrecused, first, posn, incr,
  73.   ascii                                      :    integer;
  74.  
  75.   numvalue, targetvalue                      :    real;
  76.  
  77.   labellength, datalen, dataform,
  78.   labelposn, dataposn, row,
  79.   column, fieldnbr                  :    array[1..32] of integer;
  80.   lbl                               :    array[1..384] of char;
  81.   getdata                           :    Range;
  82.  
  83.   source                            :    file;
  84.  
  85. {================================================================}
  86. {        BINARY CODED DECIMAL TO INTEGER FUNCTION                }
  87. {================================================================}
  88. function BcdToInt (cha : char) : integer;
  89. begin
  90.   BcdToInt := ord(cha) - trunc(ord(cha)/16)*6;
  91. end;
  92. {================================================================}
  93. {             CHARACTER TO INTEGER FUNCTION                      }
  94. {================================================================}
  95. function ChrToInt(var charray : Range; start, len : integer)  : integer;
  96. var
  97.   code, result : integer;
  98.   workstring   : string[10];
  99. begin
  100.   workstring := '';
  101.   for result := 0 to len-1  do
  102.     begin
  103.       if charray[start + result ] = ' ' then
  104.         workstring := workstring + '0'
  105.       else workstring := workstring + charray[start+result];
  106.     end;
  107.   val(workstring,result,code);
  108.   ChrToInt := result;
  109. end;
  110. {================================================================}
  111. {                   BIG CURSOR PROCEDURE                         }
  112. {================================================================}
  113. procedure CursOn;
  114. var
  115.   result      : record
  116.       ax,bx,cx,dx,bp,si,di,ds,es,flags : integer;
  117.       end;
  118. begin
  119.   if Mem[$0000:$0449] = 7 then
  120.       result.cx := $000d
  121.   else
  122.       result.cx := $0007;
  123.   result.ax := $0100;
  124.   Intr($10,result);
  125. end;
  126. {================================================================}
  127. {                   REGULAR VIDEO PROCEDURE                      }
  128. {================================================================}
  129. procedure RegVideo;
  130. begin
  131.   TextColor(yellow);
  132.   TextBackGround(blue);
  133. end;
  134. {================================================================}
  135. {                   REVERSE VIDEO PROCEDURE                      }
  136. {================================================================}
  137. procedure RevVideo;
  138. begin
  139.   TextColor(white);
  140.   TextBackGround(black);
  141. end;
  142. {================================================================}
  143. {           PRINT GETDATA PROCEDURE (TEMPORARY)                  }
  144. {================================================================}
  145. procedure PrtGetData;
  146. var w : integer;
  147.   begin
  148.     GotoXY(1,18);
  149.     for w := 1 to 128 do
  150.     write(getdata[w]);
  151.     writeln;
  152.     read(Kbd,ch);
  153.   end;
  154. {================================================================}
  155. {               GET DATA FROM ARRAY PROCEDURE                    }
  156. {================================================================}
  157. procedure GetDataFromArray(var message : String60);
  158. var w,x :  integer;
  159. begin
  160.   message := '';
  161.   for w := precbyte+dataposn[z] to precbyte+dataposn[z+1]-1 do
  162.     message := message + getdata[w];
  163.   if dataform[z] <> ascii then      { CHANGE TRAILING MINUS SIGN }
  164.     begin                           { TO LEADING MINUS SIGN      }
  165.       x := length(message);
  166.       if message[x] = '-' then
  167.         begin
  168.           delete(message,x,1);
  169.           w := 1;
  170.           while (w<x) and (message[w] = ' ') do
  171.             w := succ(w);
  172.           insert('-',message,w);
  173.         end;
  174.     end;
  175. end;
  176. {================================================================}
  177. {                       Edit PROCEDURE                           }
  178. {================================================================}
  179. procedure Edit(var message : String60);
  180. var
  181.   w           :  integer;
  182.   decptr      :  integer;
  183.  
  184. begin
  185.   if length(message) > 0 then
  186.     begin
  187.       if dataform[z] = 0 then decptr := datalen[z]-2
  188.       else decptr := datalen[z]-dataform[z]-3;
  189.       while decptr > 1 do
  190.         begin
  191.           if message[decptr-1] <> '-' then
  192.             begin
  193.               if message[decptr-1] in [' ','$'] then
  194.                 insert(' ',message,decptr)
  195.               else insert(',',message,decptr);
  196.             end;
  197.           decptr := decptr -3;
  198.         end;
  199.     end; { IF LENGTH BEGIN }
  200. end;
  201. {================================================================}
  202. {               Tide (Edit BACKWARDS) PROCEDURE                  }
  203. {================================================================}
  204. procedure Tide( var message : String60);
  205. var w  :  integer;
  206. begin
  207.   w := length(message);
  208.   while w>0 do
  209.     begin
  210.       if message[w] in [',', '$', '+'] then
  211.         begin
  212.           delete(message,w,1);
  213.           message := ' ' + message;
  214.         end
  215.       else w := w-1;
  216.     end;
  217. end;
  218. {================================================================}
  219. {                         Beep PROCEDURE                         }
  220. {================================================================}
  221. procedure Beep;
  222. begin
  223.   Sound(800);
  224.   Delay(100);
  225.   NoSound;
  226. end;
  227. {================================================================}
  228. {               STRING TO REAL NUMBER PROCEDURE                  }
  229. {================================================================}
  230. procedure StringToReal(var source:String60;var numb:real;var code:integer);
  231. var
  232.   x,w  :  integer;
  233. begin
  234.   w := 1;
  235.   while (w < length(source)+1) and (source[w] = ' ') do
  236.     w := w+1;
  237.   x := w;
  238.   while (w < length(source)+1) and (source[w] <> ' ') do
  239.     w := w+1;
  240.   source := copy(source,x,w-x);
  241.   val( source,numb,code );
  242.   if code <> 0 then Beep;
  243. end;
  244. {================================================================}
  245. {           STORE DATA IN ARRAY GETDATA PROCEDURE                }
  246. {================================================================}
  247. procedure StoreDataInArray;
  248.  
  249. begin
  250.   first := 1;
  251.   if dataform[z] <> ascii then
  252.     begin                       { RIGHT JUSTIFY NUMBER }
  253.       if length(ans) > 0 then StringToReal(ans,numvalue,code)
  254.         else numvalue := 0;
  255.       str(numvalue:20:8,ans);
  256.       first := pos('.',ans)-datalen[z];
  257.       if dataform[z] <> 0 then first := first + dataform[z] + 1;
  258.       if dataform[z] = ascii then first := 1;
  259.     end;
  260.   FillChar(getdata[precbyte+dataposn[z]],datalen[z],' ');
  261.   Move(ans[first],getdata[precbyte+dataposn[z]],datalen[z]);
  262. end;
  263.  
  264. {================================================================}
  265. {                  WRITE MESSAGE PROCEDURE                       }
  266. {================================================================}
  267. procedure WriteMessage(var message : String60);
  268. begin
  269.   RevVideo;
  270.   write(message);
  271.   RegVideo;
  272. end;
  273.  
  274. {================================================================}
  275. {                      KEYIN PROCEDURE                           }
  276. {================================================================}
  277. procedure KeyIn(var message : String60; xpos,ypos,len : integer);
  278.  
  279. const
  280.   controls       : set of char = [^h..^r,^u..^y,^[..^_,'\'];
  281.  
  282. var
  283.   w, count       :  integer;
  284.   fldlen         :  integer;
  285.   condition      :  boolean;
  286.  
  287. begin
  288.   if dataform[z]  = ascii then fldlen := len
  289.   else
  290.     begin
  291.       if dataform[z] = 0 then fldlen := len +((len-1)div 3)
  292.       else fldlen := len+((len-dataform[z]-2)div 3);
  293.       Edit(message);
  294.     end;
  295.   count := 0;
  296.     if length(message)>fldlen then message := copy(message,1,fldlen);
  297.     if dataform[z] <> ascii then Tide(message);
  298.     GotoXY(xpos,ypos);
  299.     WriteMessage(message);
  300.     GotoXY(xpos+count,ypos);
  301.     repeat
  302.       read (Kbd,ch);
  303.       if ch = #27 then
  304.         read (Kbd,ch1)
  305.       else ch1 := ' ';  { INTIIALIZE FOR CHAR WHICH FOLLOWS ESC }
  306.  
  307.       if abortchar = true then            { THIS CODE IS REQUIRED TO  }
  308.         begin                             { ELIMINATE THE ENTRY OF    }
  309.           abortchar := false;             { UNWANTED CHARACTERS AFTER }
  310.           ch := ^s;                       { A SEARCH IS ABORTED       }
  311.         end;
  312.       case ch of
  313.  
  314.         ^a  :                                    { LEFT ONE WORD }
  315.             begin
  316.               while(message[count-1] = ' ') and (count>1) do
  317.                 count := pred(count);
  318.               while(message[count-1] <> ' ') and (count>1) do
  319.                 count := pred(count);
  320.               if count>0 then count := pred(count);
  321.             end;
  322.  
  323.         ^c  :          { EXIT FIELD MODE, RETURN TO RRECORD MODE }
  324.             begin
  325.               ch  := #27;              { SAME AS F1 FUNCTION KEY }
  326.               ch1 := #59;
  327.             end;
  328.  
  329.         ^d  :                                { RIGHT 1 CHARACTER }
  330.             begin
  331.               if count < len then count := count +1;
  332.             end;
  333.  
  334.         ^e  :
  335.             begin
  336.               ch := #27;          { CTRL E = WORDSTAR'S UP 1 LINE }
  337.               ch1 := #64;
  338.             end;
  339.  
  340.         ^f  :                                     { RIGHT 1 WORD }
  341.             begin
  342.               while(message[count+1] <> ' ') and (count<fldlen) do
  343.                 count := succ(count);
  344.               while(message[count+1] = ' ') and (count<fldlen) do
  345.                 count := succ(count);
  346.             end;
  347.  
  348.         ^g  :                    { DELETE CHARACTER UNDER CURSOR }
  349.             begin
  350.               if count>=0 then
  351.                 begin
  352.                   message := message + ' ';
  353.                   delete(message,count+1,1);
  354.                   GotoXY(xpos,ypos);
  355.                   WriteMessage(message);
  356.                 end;
  357.             end;
  358.  
  359.         ^i  :                { TAB = MOVE CURSOR 6 CHAR TO RIGHT }
  360.             begin
  361.               count := count + 6;
  362.               if count > len then count := len;
  363.             end;
  364.  
  365.         ^q  :  count := 0;                  { CURSOR TO LEFT END }
  366.  
  367.         ^s  :                                 { LEFT 1 CHARACTER }
  368.             begin
  369.               if count >0 then count := count -1;
  370.             end;
  371.  
  372.         ^t  :                             { DELETE WORD TO RIGHT }
  373.             begin
  374.               w := fldlen - count;
  375.               if message[count+1] = ' ' then
  376.                 begin
  377.                  while (message[count+1] = ' ') and (w>0) do
  378.                    begin
  379.                     delete(message,count+1,1);
  380.                     message := message + ' ';
  381.                     w := pred(w);
  382.                   end;
  383.                 end
  384.               else
  385.                 begin
  386.                   while message[count+1] <> ' ' do
  387.                     begin
  388.                       delete (message,count+1,1);
  389.                       message := message + ' ';
  390.                       w := pred(w);
  391.                     end;
  392.                   while (message[count+1] = ' ') and (w>0) do
  393.                     begin
  394.                       delete (message,count+1,1);
  395.                       message := message + ' ';
  396.                       w := pred(w);
  397.                     end;
  398.                 end;
  399.               GotoXY(xpos,ypos);
  400.               WriteMessage(message);
  401.             end;
  402.  
  403.         ^w  :  count := len-1;               { CURSOR TO RIGHT END }
  404.  
  405.         ^x  :  ch := ^m;                { WORDSTAR'S DOWN 1 LINE }
  406.  
  407.         ^y  :                           { WORDSTAR'S CLEAR FIELD }
  408.             begin
  409.               message := '';
  410.               for w := 1 to fldlen do
  411.               message := message + '_';
  412.               GotoXY(xpos,ypos);
  413.               WriteMessage(message);
  414.             end;
  415.  
  416.         ^z  :                         { CLEAR REMAINDER OF FIELD }
  417.             begin
  418.               for w := count +1 to fldlen+1 do
  419.                   message[w] := '_';
  420.               if length(message)>fldlen then
  421.                 message := copy(message,1,fldlen);
  422.               GotoXY(xpos,ypos);
  423.               WriteMessage(message);
  424.             end;
  425.  
  426.         ^h  :                  { DELETE CHARACTER BEFORE CURSOR }
  427.             begin
  428.               if count>0 then
  429.                 begin
  430.                   delete(message,count,1);
  431.                   message := message + ' ';
  432.                   if length(message)>fldlen then
  433.                     message := copy(message,1,fldlen);
  434.                   GotoXY(xpos,ypos);
  435.                   WriteMessage(message);
  436.                   count := count-1;
  437.                 end;
  438.             end;
  439.  
  440.  
  441.       end; { CASE CH OF }
  442.  
  443.       if ord(ch) in [32..91,93..126] then    { PROCESS IF ALPHA/NUMERIC }
  444.         begin
  445.           if count < fldlen then
  446.             begin
  447.               count := count +1;
  448.               insert(ch,message,count);
  449.               if length(message)>fldlen then
  450.                 message := copy(message,1,fldlen);
  451.               GotoXY(xpos,ypos);
  452.               WriteMessage(message);
  453.             end;
  454.         end;
  455.       GotoXY(xpos+count,ypos);
  456.  
  457.  
  458.     until ch in [#27,^j..^m,^r,^v,'\']; { EXIT KEYIN ONLY ON THESE CHAR }
  459.  
  460.  
  461.     if dataform[z] <> ascii then Tide(message);  {ELIM COMMAS IF NUMERIC}
  462.     if length(message)>0 then
  463.       begin
  464.         if ch = ^m then ch := message[1];
  465.       end;
  466.     count := fldlen+1;
  467.     condition := false;
  468.     repeat                     { ESTABLISH END OF DATA IN STRING }
  469.       count := count -1;
  470.       if message[count] = '_' then message[count] := ' ';
  471.       if message[count] <> ' ' then condition := true;
  472.       if count = 0 then condition := true;
  473.     until condition = true;
  474.     message := copy(message,1,count);
  475. end;
  476. {================================================================}
  477. {           CALCULATE DISKRECORD & PRECBYTE PROCEDURE            }
  478. {================================================================}
  479. procedure Calculate;
  480.   begin
  481.     diskrecord := trunc((datarecord-1)/blockingfactor)*2+7;
  482.     precbyte := ((datarecord-1) mod blockingfactor)*rcdlen;
  483.   end;
  484. {================================================================}
  485.  
  486. {================================================================}
  487. {                   GET DATA RECORD PROCEDURE                    }
  488. {================================================================}
  489. procedure GetDataRec;
  490.   begin
  491.     Calculate;
  492.     if diskrecord <> diskrecnowinmem then
  493.       begin
  494.         if filerecchgd = true then
  495.           begin
  496.             if diskrecnowinmem > nbrdiskrecused then
  497.               begin                 { GET NEXT AVAILABLE RECORD }
  498.                 Seek(source,nbrdiskrecused+2);
  499.                 nbrdiskrecused := diskrecnowinmem;
  500.               end
  501.             else
  502.               begin
  503.                 Seek(source,diskrecnowinmem);
  504.               end;
  505.             blockwrite(source,getdata,2);  {SAVE CHANGED DATA}
  506.             filerecchgd := false;
  507.             changedate := true;
  508.           end;
  509.  
  510.         if diskrecord <= nbrdiskrecused then
  511.           begin
  512.             Seek(source,diskrecord);
  513.             blockread(source,getdata,2);         {  RECORD DATA  }
  514.          end
  515.         else FillChar(getdata[1],256,' '); {SPACES FOR EMPTY REC }
  516.  
  517.        diskrecnowinmem := diskrecord;
  518.       end;
  519.   end;
  520. {================================================================}
  521. {              PRINT LABEL AND DATA PROCEDURE                    }
  522. {================================================================}
  523. procedure PrintLabDat( z : integer );
  524. var
  525.   w  :  integer;
  526.  
  527.   begin
  528.     if row[z] <23 then
  529.       begin
  530.         GotoXY(column[z],row[z]);
  531.         for w := labelposn[z] to labelposn[z+1]-1 do
  532.         write (lbl[w]);
  533.         ans := '';
  534.         GetDataFromArray(ans);
  535.         if dataform[z] <> ascii then Edit(ans);
  536.         write(': ' + ans);
  537.       end;
  538.   end;
  539. {================================================================}
  540. {                 DISPLAY ONE RECORD PROCEDURE                   }
  541. {================================================================}
  542. procedure DisplayRec;
  543. begin
  544.   ClrScr;
  545.   for z := 1 to fieldperrecord do
  546.   PrintLabDat(z);
  547.   GotoXY(70,23);
  548.   write('RECORD ',datarecord);
  549.   lastrecused := datarecord;
  550. end;
  551. {================================================================}
  552. {                 FIELD DATA MESSAGE PROCEDURE                   }
  553. {================================================================}
  554. procedure FieldDataMsg;
  555. begin
  556.   GotoXY(1,24);
  557.   write('FIELD DATA Edit MODE     [ USE WORDSTAR Edit ');
  558.   write('COMMANDS ]       F1 = RECORD DONE');
  559. end;
  560. {================================================================}
  561. {                  DELETE RECORD PROCEDURE                       }
  562. {================================================================}
  563. procedure DeleteRec;
  564.   begin
  565.     GotoXY(1,24);
  566.     ClrEol;
  567.     write('OK TO DELETE (Y/N)  ');
  568.     read(Kbd,ch);
  569.     if ch in ['Y','y'] then
  570.       begin
  571.         FillChar(getdata[precbyte+1],rcdlen,' ');
  572.         filerecchgd := true;
  573.         DisplayRec;
  574.       end;
  575.    end;
  576. {================================================================}
  577. {                   ENTER TARGET PROCEDURE                       }
  578. {================================================================}
  579. procedure EnterTarget;
  580. begin
  581.   GotoXY(1,24);
  582.   write('ENTER TARGET : ');
  583.   ClrEol;
  584.   target := '';
  585.   KeyIn(target,16,24,20);
  586.   case ch1 of
  587.     #67,#68 :
  588.           begin
  589.             target := lasttarget;
  590.             GotoXY(16,24);
  591.             RevVideo;
  592.             write(target);
  593.             RegVideo;
  594.           end
  595.     else  { CASE TARGET[1] OF }
  596.           begin
  597.             lasttarget := target;
  598.           end;
  599.     end;  { CASE TARGET[1] OF }
  600. end;
  601. {================================================================}
  602. {                  ENTER FIELD DATA PROCEDURE                    }
  603. {================================================================}
  604. procedure EnterField;
  605. var
  606.   w     :  integer;
  607.  
  608. begin
  609.   z := 1;
  610.   repeat
  611.     begin
  612.       GetDataFromArray(ans);
  613.       KeyIn(ans,column[z]+labellength[z]+2,row[z],datalen[z]);
  614.       case ch of
  615.  
  616.         '\'    :
  617.           begin                 { PROCESS BACKSLASH COMMANDS }
  618.             PrintLabDat(z);
  619.             GotoXY(1,23);
  620.             write('FIELD NAME...');
  621.             EnterTarget;
  622.             DelLine;
  623.             z := 0;
  624.             repeat
  625.               z := z + 1;
  626.               ans := '';
  627.               for w := labelposn[z] to labelposn[z+1]-1 do
  628.               ans := ans + lbl[w];
  629.               posn := pos(target,ans);
  630.               if z = fieldperrecord then
  631.                 begin
  632.                   if posn = 0 then
  633.                     begin
  634.                       z := 1;
  635.                       posn := 1;
  636.                     end;
  637.                 end;
  638.             until posn <> 0;
  639.             GotoXY(1,23);
  640.             write('             ');
  641.             FieldDataMsg;
  642.           end;
  643.  
  644.         ^r  :                        { ^R = MOVE TO TOP OF FIELD }
  645.           begin
  646.             PrintLabDat(z);
  647.             StoreDataInArray;
  648.             filerecchgd := true;
  649.             z := 1;
  650.           end;
  651.  
  652.         #27 :
  653.           begin
  654.             case ch1 of
  655.  
  656.             #59 :              { F1 KEY FOR HOME TO RECORD MODE }
  657.                begin
  658.                  StoreDataInArray;
  659.                  filerecchgd := true;
  660.                  PrintLabDat(z);
  661.                  z := fieldperrecord + 1;          { HOME KEY   }
  662.                end;
  663.  
  664.  
  665.             #64 :                      { F6 = UP ARROW FUNCTION }
  666.                begin
  667.                  StoreDataInArray;
  668.                  filerecchgd := true;
  669.                  PrintLabDat(z);
  670.                  if z>1 then z := z-1              { UP ARROW   }
  671.                  else z := fieldperrecord;
  672.                end;
  673.  
  674.             #60,#66 :         { F2 = LINE FEED, F6 = DOWN ARROW }
  675.                begin
  676.                  StoreDataInArray;
  677.                  filerecchgd := true;
  678.                  PrintLabDat(z);
  679.                  z := z+1;             { LINE FEED & DOWN ARROW }
  680.                end;
  681.  
  682.  
  683.  
  684.             #67,#68  :            { UP [F9] OR DOWN [F10] SEARCH }
  685.                begin
  686.                  w := z;   { SAVE FIELD NUMBER }
  687.                  condition := false;
  688.                  GotoXY(1,23);
  689.                  if ch1 = #68 then
  690.                    begin
  691.                      incr := 1;
  692.                      write('SEARCH UP...');
  693.                      if datarecord = nbrrecused then condition := true;
  694.                    end
  695.                  else
  696.                    begin
  697.                      incr := -1;
  698.                      write('SEARCH DOWN...');
  699.                      if datarecord = 1 then condition := true;
  700.                    end;
  701.                  EnterTarget;
  702.                  if length(target)>0 then
  703.                    begin
  704.                      if dataform[z] <> ascii then
  705.                        begin
  706.                          if (target[1] = '>') or (target[1]='<') then
  707.                            begin
  708.                              searchtype := target[1];
  709.                              target := copy(target,2,length(target)-1);
  710.                            end
  711.                          else searchtype := '=';
  712.                          StringToReal(target,targetvalue,code);
  713.                        end;
  714.                      while condition = false do
  715.                        begin
  716.                          datarecord := datarecord + incr;
  717.                          GetDataRec;
  718.                          GotoXY(70,23);
  719.                          ClrEol;
  720.                          write('RECORD ',datarecord);
  721.                          GetDataFromArray(ans);
  722.                          if dataform[z] <> ascii then
  723.                            begin
  724.                              StringToReal(ans,numvalue,code);
  725.                              case searchtype of
  726.                                '>' : if numvalue>targetvalue then
  727.                                      condition := true;
  728.                                '<' : if numvalue<targetvalue then
  729.                                      condition := true;
  730.                                '=' : if numvalue = targetvalue then
  731.                                      condition := true;
  732.                              end; { CASE SEARCHTYPE }
  733.                            end
  734.                          else
  735.                            begin
  736.                              posn := pos(target,ans);
  737.                              if posn <> 0 then condition := true;
  738.                            end;
  739.                          if datarecord >= nbrrecused then condition := true;
  740.                          if datarecord <= 1 then condition := true;
  741.                          if KeyPressed = true then
  742.                            begin
  743.                             condition := true;
  744.                             abortchar := true;
  745.                            end;
  746.                        end; { WHILE CONDITION... }
  747.                      DisplayRec;
  748.                    end
  749.                  else
  750.                    begin
  751.                      GotoXY(1,23);
  752.                      write('              ');
  753.                    end;
  754.                  FieldDataMsg;
  755.                  z := w;   { RESTORE FIELD NUMBER }
  756.                end;  { CASE OF ^L (UP ARROW) OR ^H (DOWN ARROW) }
  757.  
  758.  
  759.             end;  { CASE OF #27 }
  760.           end;  { #27 BEGIN }
  761.       else { CASE CH OF }
  762.           begin
  763.             StoreDataInArray;
  764.             filerecchgd := true;
  765.             PrintLabDat(z);
  766.             z := z+1;
  767.           end;  { ELSE BEGIN }
  768.       end; { CASE CH OF }
  769.     end; {REPEAT BEGIN }
  770.   until z > fieldperrecord;
  771. end;
  772.  
  773. {===============================================================}
  774. {                       FUNCTION EXIST                          }
  775. {===============================================================}
  776. function Exist(filename : NameStr) : boolean;
  777. var
  778.   fil :  file;
  779.   status : Integer;
  780.  
  781. begin
  782.   Assign(fil,filename);
  783.   {$I-}
  784.   reset(fil);
  785.   {$I+}
  786.   Exist := (IOResult = 0);
  787. {$I-} Close(fil); status := IOResult; {$I+} (* Required by Turbo 3.x *)
  788. end;                                        (* Added by Doug Stevens *)
  789. {================================================================}
  790. {               IDENTIFY DATA RECORD PROCEDURE                   }
  791. {================================================================}
  792. procedure IdRecord;
  793. begin
  794.   GotoXY(1,24);
  795.   write('ENTER RECORD NUMBER : ');
  796.   read(datarecord);
  797.   if datarecord> nbrrecused then datarecord := nbrrecused;
  798.   if datarecord< 1 then datarecord := 1;
  799.   lastrecused := datarecord+1;        { FORCE DISPLAY AFTER MENU }
  800.   TextMode(c80);
  801.   RegVideo;
  802.   ClrScr;
  803. end;
  804. {================================================================}
  805. {               ADD / ENTER RECORDS PROCEDURE                    }
  806. {================================================================}
  807. procedure AddNewRecord;
  808. begin
  809.   TextMode(c80);
  810.   RegVideo;
  811.   repeat
  812.     nbrrecused := nbrrecused + 1;
  813.     datarecord := nbrrecused;
  814.     GetDataRec;
  815.     DisplayRec;
  816.     GotoXY(1,24);
  817.     write('ADD/ENTER RECORD MODE     [ USE WORDSTAR Edit ');
  818.     write('COMMANDS ]         F1 KEY TO END');
  819.       repeat
  820.         EnterField;
  821.         GotoXY(1,24);
  822.         ClrEol;
  823.         write('DATA RECORD OK? (Y/N/<F1>) ');
  824.         write('    ');
  825.         TextColor(white+blink);
  826.         TextBackGround(red);
  827.         write('<F1> KEY FOR MENU');
  828.         RegVideo;
  829.         GotoXY(28,24);
  830.         read(Kbd,ch);
  831.         if ch = #27 then read(Kbd,ch1) else ch1 := #0;
  832.       until ch <> 'N';
  833.   until ch1 = #59;
  834.   filerecchgd := true;
  835.   recaddedtofile := true;
  836.   lastrecused := datarecord;
  837.   datarecord := 0;                   { A READ OF DATA RECORD 0 }
  838.   GetDataRec;                        { WILL WRITE LAST RECORD  }
  839.  end;
  840. {================================================================}
  841. {             DISPLAY RECORDS TO END PROCEDURE                   }
  842. {================================================================}
  843. procedure DisplayRecords;
  844. begin
  845.   IdRecord;
  846.   repeat
  847.     Calculate;
  848.     GetDataRec;
  849.     if lastrecused <> datarecord then
  850.       begin
  851.         lastrecused := datarecord;
  852.         DisplayRec;
  853.       end;
  854.     GotoXY(1,24);
  855.     write('RETURN TO CONTINUE :         [ F2 TO ENTER DATA ]    ');
  856.     write('      F1 = RETURN TO MENU');
  857.     GotoXY(22,24);
  858.     read(Kbd,ch);
  859.     if ch <> #27 then
  860.       begin
  861.         case ch of
  862.           ^d,^f,^m  :  if datarecord <nbrrecused+1 then { RETURN KEY }
  863.                datarecord := datarecord +1;
  864.  
  865.           ^h  :  DeleteRec;                             { DELETE KEY }
  866.  
  867.           ^a,^s  :  if datarecord > 1 then         { F9 = LEFT ARROW }
  868.              datarecord := datarecord -1;
  869.  
  870.           ^e,^c,^r,^x  :               { WORDSTAR'S UP FIELD COMMAND }
  871.              begin
  872.                FieldDataMsg;
  873.                EnterField;
  874.              end;
  875.  
  876.         end; { CASE CH OF }
  877.       end
  878.     else
  879.       begin
  880.         read(Kbd,ch1);
  881.         case ch1 of
  882.  
  883.            #68  :  if datarecord < nbrrecused+1 then  { F10 = RIGHT ARROW }
  884.              datarecord := datarecord +1;
  885.  
  886.            #59  :  datarecord := nbrrecused +1   ;    { F1 = HOME KEY  }
  887.  
  888.            #67  :  if datarecord > 1 then            { F9 = LEFT ARROW }
  889.              datarecord := datarecord -1;
  890.  
  891.            #60,#65,#66  :
  892.              begin                             { LINE FEED }
  893.                FieldDataMsg;
  894.                EnterField;
  895.              end;
  896.         end; { CASE CH OF }
  897.       end;  { ELSE BEGIN  }
  898.   until datarecord > nbrrecused;
  899. end;
  900. {================================================================}
  901. {                  CORRECT RECORD PROCEDURE                      }
  902. {================================================================}
  903. procedure CorrectRecord;
  904. begin
  905.   IdRecord;
  906.   Calculate;
  907.   GetDataRec;
  908.   DisplayRec;
  909.   FieldDataMsg;
  910.   repeat
  911.     EnterField;
  912.     GotoXY(1,24);
  913.     write('DATA RECORD OK? (Y/N) ');
  914.     ClrEol;
  915.     read(Kbd,ch);
  916.     FieldDataMsg;
  917.   until ch <> 'N';
  918. end;
  919.  
  920. {################################################################}
  921. {                                                                }
  922. {                         MAIN PROGRAM                           }
  923. {                         ============                           }
  924. {################################################################}
  925.  
  926.  
  927. begin
  928. FLIERSTART:
  929.   repeat
  930.     TextMode(c40);
  931.     RegVideo;
  932.     ClrScr;
  933.     GotoXY(1,22);
  934.     write('FILER A LA PASCAL');
  935.     GotoXY(1,23);
  936.     write('ENTER SOURCE FILE NAME : ');
  937.     readln(sourcename);
  938.     x := pos('.',sourcename);
  939.     if x <> 0 then sourcename := copy(sourcename,1,x-1);
  940.     sourcename := sourcename + '.DAT';
  941.     fileexists := Exist(sourcename);
  942.   until fileexists = true;
  943.   write('ENTER CURRENT DATE (MM/DD/YY) : ');
  944.   readln( currdate );
  945.   if length(currdate) = 0 then currdate := '  /  /  ';
  946.   Assign( source, sourcename );
  947.   reset( source );
  948.   Seek(source,1);
  949.   blockread( source,getdata,1 );
  950.   blockread( source,lbl,3 );
  951.   filename := 'XXXXXX';
  952.   for x := 1 to 6 do
  953.     filename[x] := getdata[x];
  954.   maxnbrrec := ChrToInt(getdata,7,4);
  955.   nbrrecused := ChrToInt(getdata,11,4);
  956.   rcdlen := ChrToInt(getdata,15,3);
  957.   blockingfactor := ChrToInt(getdata,18,2);
  958.   fieldperrecord := ChrToInt(getdata,20,2);
  959.   filedate := '  /  /  ';
  960.   Move(getdata[22],filedate[1],8);
  961.  
  962. {================================================================}
  963. {  GET LABEL LENGTH, DATA LENGTH & DATA FORM INFO                }
  964. {================================================================}
  965.  
  966. labelposn[1] := 1;
  967. dataposn[1] := 1;
  968.  
  969. for x := 1 to fieldperrecord do
  970.   begin
  971.     labellength[x] :=  BcdToInt(getdata[32+x]);
  972.     datalen[x]     :=  BcdToInt(getdata[64+x]);
  973.     dataform[x]    :=  ord(getdata[96+x])-48;
  974.     labelposn[x+1] :=  labelposn[x] + labellength[x];
  975.     dataposn[x+1]  :=  dataposn[x] + datalen[x];
  976.   end;
  977.  
  978. {================================================================}
  979. {           TRANSLATE REPORT STRUCTURE                           }
  980. {================================================================}
  981.  
  982.   blockread(source,getdata,1);  { SCREEN INFORMATION }
  983.       { ESTABLISH VALUE OF DATAFORM[Z] FOR ASCII INFORMATION }
  984.       if getdata[1] = 'S' then ascii := 9 else ascii := 15;
  985.   for x := 1 to fieldperrecord do
  986.     begin
  987.       w := x*4+1;
  988.       row[x]       := BcdToInt(getdata[w]);
  989.       column[x] := BcdToInt(getdata[w+1])*10+trunc(BcdToInt(getdata[w+2])/10);
  990.       {FIELDNBR[X]  := BcdToInt(GETDATA[W+3]);} { not implemented }
  991.     end;
  992. {================================================================}
  993. {          INITIALIZE VARIABLES FOR ENTRY INTO FILER             }
  994. {================================================================}
  995.   datarecord := nbrrecused;
  996.   Calculate;
  997.   abortchar := false;         { FLAG TO INDICATE ABORT OF SEARCH }
  998.   changedate := false;  { FLAG TO INDICATE THAT DATA HAS CHANGED }
  999.   diskrecnowinmem := diskrecord -1; { ENSURE DISK READ FIRST TIME}
  1000.   filerecchgd := false;      { ENSURE NO WRITE BEFORE FIRST READ }
  1001.   lastrecused := 0;               { SET LAST RECORD USED TO ZERO }
  1002.   lasttarget := '';     { ENSURE THERE IS A TARGET TO SEARCH FOR }
  1003.   nbrdiskrecused := diskrecord;     { ESTABLISH MAX DISK REC NBR }
  1004.   recaddedtofile := false; { FLAG TO INDICATE CHANGE IN FILE SIZE}
  1005. {================================================================}
  1006. {               MASTER MENU                                      }
  1007. {================================================================}
  1008.  
  1009.   repeat
  1010.     TextMode(c40);
  1011.     RegVideo;
  1012.     ClrScr;
  1013.     GotoXY(1,10);
  1014.     writeln ('FILER MASTER MENU');
  1015.     writeln ('=================');
  1016.     writeln ('FILE : ',filename);
  1017.     writeln ('LAST CHANGE : ',filedate);
  1018.     writeln('ACTIVE RECORDS : ',nbrrecused);
  1019.     writeln('LAST RECORD : ',lastrecused);
  1020.     writeln;
  1021.     writeln ('1. ADD/ENTER RECORDS');
  1022.     writeln ('2. DISPLAY RECORDS');
  1023.     writeln ('3. CORRECT RECORDS');
  1024.     writeln ('4. DELETE RECORD');
  1025.     writeln ('5. END FILER PROGRAM');
  1026.     writeln;
  1027.     write ('ENTER OPTION : ');
  1028.     read(option);
  1029.         case option of
  1030.           '1'  :   AddNewRecord;
  1031.           '2'  :   if nbrrecused > 0 then DisplayRecords;
  1032.           '3'  :   if nbrrecused > 0 then CorrectRecord;
  1033.           '4'  :   if nbrrecused > 0 then
  1034.                      begin
  1035.                        IdRecord;
  1036.                        GetDataRec;
  1037.                        DisplayRec;
  1038.                        DeleteRec;
  1039.                      end;
  1040.         end;
  1041.   until option in  ['5','9'];
  1042. {================================================================}
  1043. {                    END PROGRAM                                 }
  1044. {================================================================}
  1045.   if filerecchgd = true then
  1046.     begin                            { WRITE LAST CHANGED RECORD }
  1047.       Seek(source,diskrecnowinmem);
  1048.       blockwrite(source,getdata,2);
  1049.       changedate := true;
  1050.     end;
  1051.  
  1052.   if recaddedtofile = true then
  1053.     begin
  1054.       Seek(source,0);                   { UPDATE BASIC/Z BLOCK 0 }
  1055.       blockread(source,getdata,1);
  1056.       x := (nbrrecused+blockingfactor-1) div blockingfactor +3;
  1057.       getdata[3] := chr(x-((x div 256)*256));
  1058.       getdata[4] := chr(x div 256);
  1059.       Seek(source,0);
  1060.       blockwrite(source,getdata,1);
  1061.     end;
  1062.  
  1063.   Seek(source,1);                   { UPDATE FILER HEADER RECORD }
  1064.   blockread(source,getdata,1);
  1065.   str(nbrrecused:4,ans);
  1066.   Move(ans[1],getdata[11],4);
  1067.   if changedate = true then Move(currdate[1],getdata[22],8);
  1068.   filedate := currdate;
  1069.   Seek(source,1);
  1070.   blockwrite(source,getdata,1);
  1071.   close(source);
  1072.   TextMode(c80);
  1073.   if option = '9' then goto FLIERSTART;
  1074.   GotoXY(1,22);
  1075.   writeln;
  1076.   writeln('THANK YOU FOR USING FILER');
  1077.   writeln;
  1078.   writeln('HAVE A GREAT DAY!');
  1079.  
  1080. {================================================================}
  1081. end.
  1082.